import  tensorflow as tf

from  tensorflow import keras

from  tensorflow.keras import  layers

import numpy as np

# 模型子类化
# 4.2 模型子类化
# 可以通过对 tf.keras.Model 进行子类化并定义自己的前向传播来构建完全可自定义的模型。
#
# 在_init_ 方法中创建层并将它们设置为类实例的属性。
# 在__call__方法中定义前向传播

class MyModel(tf.keras.Model):
    def __init__(self,num_classes = 10):
        super(MyModel,self).__init__(name='my_model')
        self.num_classes = num_classes
        # 定义网络层
        self.layer1 = layers.Dense(32,activation=tf.keras.activations.relu)
        self.layer2 = layers.Dense(num_classes,activation=tf.keras.activations.softmax)
    def call(self, inputs):
        #定义向前传播
        h1 = self.layer1(inputs)
        out = self.layer2(h1)
        return out

    def compute_output_shape(self, input_shape):
        # 计算输出shape
        shape = tf.TensorShape(input_shape).as_list()
        shape[-1] = self.num_classes
        return  tf.TensorShape(shape)

# 模型实例化并且进行使用

model = MyModel(num_classes= 10 )

model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
              loss=tf.keras.losses.categorical_crossentropy,
              metrics=[tf.keras.metrics.categorical_accuracy])




train_x = np.random.random((1000, 72))
train_y = np.random.random((1000, 10))

val_x = np.random.random((200, 72))
val_y = np.random.random((200, 10))
# 训练模型
model.fit(train_x,train_y,epochs= 10,batch_size= 32) # 不能添加校验数据，否则报错数据结构不对




